home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 60.zip / BS1 part 60 / C mon v3 d3.adf / CMANV3_3.LHA / ACE9.lha / Devices / AudioDevice / Example3.c < prev    next >
C/C++ Source or Header  |  1992-04-24  |  12KB  |  387 lines

  1. /***********************************************************/
  2. /*                                                         */
  3. /* Amiga C Encyclopedia (ACE) V3.0      Amiga C Club (ACC) */
  4. /* -------------------------------      ------------------ */
  5. /*                                                         */
  6. /* Book:    ACM Devices                 Amiga C Club       */
  7. /* Chapter: AudioDevice                 Tulevagen 22       */
  8. /* File:    Example3.c                  181 41  LIDINGO    */
  9. /* Author:  Anders Bjerin               SWEDEN             */
  10. /* Date:    92-04-21                                       */
  11. /* Version: 1.00                                           */
  12. /*                                                         */
  13. /*   Copyright 1992, Anders Bjerin - Amiga C Club (ACC)    */
  14. /*                                                         */
  15. /* Registered members may use this program freely in their */
  16. /*     own commercial/noncommercial programs/articles.     */
  17. /*                                                         */
  18. /***********************************************************/
  19.  
  20. /* This program demonstrates how you can play some sampled   */
  21. /* data. Remeber that sampled data is just a more complicatd */
  22. /* waveform.                                                 */
  23. /*                                                           */
  24. /* The sampled sound has been converted into numbers by      */
  25. /* "PrintSound", a utilitiy included in the "Sound" manual.  */
  26.  
  27.  
  28.  
  29. #include <exec/types.h>        /* STRPTR         */
  30. #include <exec/memory.h>       /* MEMF_CHIP      */
  31. #include <devices/audio.h>     /* Audio Device   */
  32.  
  33.  
  34.  
  35. /* The audio channels: (Sadly these constants */
  36. /* have not been defined in any header file.) */ 
  37.  
  38. /* Values: */
  39. #define LEFT0B   0
  40. #define RIGHT0B  1
  41. #define RIGHT1B  2
  42. #define LEFT1B   3
  43.  
  44. /* Bit fields: */
  45. #define LEFT0F   (1<<LEFT0B)
  46. #define RIGHT0F  (1<<RIGHT0B)
  47. #define RIGHT1F  (1<<RIGHT1B)
  48. #define LEFT1F   (1<<LEFT1B)
  49.  
  50. /* Sound priorities: */
  51. #define SOUND_UNSTOPPABLE  127
  52. #define SOUND_EMERGENCIES   95
  53. #define SOUND_ATTENTION     85
  54. #define SOUND_SPEECH        75
  55. #define SOUND_INFORMATION   60
  56. #define SOUND_MUSIC          0
  57. #define SOUND_EFFECT       -35
  58. #define SOUND_BACKGROUND   -90
  59. #define SOUND_SILENCE     -128
  60.  
  61. /* The clock constant: */
  62. #define NTSC_CLOCK    3579545 /* American Amigas - 60Hz */
  63. #define PAL_CLOCK     3546895 /* European Amigas - 50Hz */
  64.  
  65. /* Define min/max-volumes: */
  66. #define MAXVOLUME  64
  67. #define MINVOLUME   0
  68.  
  69.  
  70.  
  71. /* Declare a pointer to our reply port: */
  72. struct MsgPort *replymp = NULL;
  73.  
  74. /* Declare a pointer to our audio request block: */
  75. struct IOAudio *audio_req = NULL;
  76.  
  77.  
  78.  
  79. /* Our list of preffered channel combinations: */
  80. /* (First we try to reserve the first channel, */
  81. /* then the second, third and finally fourth   */
  82. /* audio channel.)                             */
  83. UBYTE allocation_array[]=
  84. {
  85.   LEFT0F,
  86.   RIGHT0F,
  87.   RIGHT1F,
  88.   LEFT1F
  89. };
  90.  
  91.  
  92.  
  93. /* Declare a pointer to some soundwave data: */
  94. BYTE *beep_wave = NULL;
  95.  
  96. /* This is some sampled sound data which will be copied */
  97. /* into some chip memory before we try to play it:      */
  98. /* (This data was converted to numbers by PrintSound.)  */
  99.  
  100. /************************************/
  101. /* SoundData prepared by PrintSound */
  102. /* Anders Bjerin       Amiga C Club */
  103. /*                                  */
  104. /* File name:              Beep.snd */
  105. /* Record Rate:               10100 */
  106. /* File Length:                 602 */
  107. /************************************/
  108.  
  109. BYTE chip beep_data[]=
  110. {
  111.   4,11,9,0,-11,-9,3,15,17,-6,-34,
  112.   -31,22,93,63,-20,-106,-85,0,104,84,-9,
  113.   -98,-68,17,114,57,-42,-109,-33,61,101,9,
  114.   -88,-95,7,101,46,-39,-109,-33,60,114,14,
  115.   -79,-79,19,112,46,-53,-111,-20,73,104,3,
  116.   -95,-80,22,111,36,-57,-111,-19,84,96,-11,
  117.   -103,-63,34,114,23,-71,-107,-7,90,82,-15,
  118.   -106,-55,47,119,22,-69,-103,-4,98,87,-20,
  119.   -107,-53,46,117,20,-77,-103,1,100,73,-25,
  120.   -111,-47,58,122,17,-77,-96,6,111,66,-26,
  121.   -107,-39,60,122,22,-79,-93,19,117,53,-39,
  122.   -109,-23,82,115,3,-90,-74,30,122,41,-57,
  123.   -111,-14,85,100,-6,-103,-68,42,123,28,-61,
  124.   -109,-11,93,101,-9,-103,-61,41,123,28,-68,
  125.   -106,-3,96,92,-11,-107,-58,52,123,19,-73,
  126.   -100,0,104,87,-20,-109,-49,55,119,12,-85,
  127.   -96,11,111,73,-25,-114,-41,68,115,4,-88,
  128.   -85,15,119,65,-38,-114,-30,73,112,4,-93,
  129.   -87,23,119,50,-42,-111,-25,79,114,3,-92,
  130.   -82,22,120,47,-52,-114,-19,82,107,-1,-100,
  131.   -73,38,122,28,-66,-101,-6,100,92,-25,-111,
  132.   -46,58,119,9,-88,-92,14,114,63,-36,-115,
  133.   -33,76,109,-4,-96,-76,23,127,58,-44,-115,
  134.   -26,76,103,0,-96,-85,19,119,57,-38,-114,
  135.   -34,74,103,-4,-96,-77,25,122,44,-57,-112,
  136.   -14,88,84,-19,-109,-61,47,123,23,-74,-103,
  137.   6,109,57,-44,-117,-33,69,111,6,-95,-88,
  138.   25,117,39,-53,-119,-25,85,100,-7,-104,-74,
  139.   33,123,36,-61,-115,-9,93,84,-15,-111,-63,
  140.   52,122,19,-73,-106,6,111,61,-33,-114,-38,
  141.   68,114,7,-84,-88,23,117,44,-50,-114,-17,
  142.   88,93,-4,-101,-76,41,120,28,-60,-107,-6,
  143.   103,80,-19,-109,-58,50,122,23,-71,-101,7,
  144.   109,68,-22,-111,-52,65,119,12,-79,-88,19,
  145.   120,58,-41,-114,-28,80,101,-1,-98,-73,42,
  146.   122,30,-61,-107,-4,106,77,-26,-106,-39,71,
  147.   109,7,-88,-88,30,119,42,-49,-109,-14,100,
  148.   92,-11,-101,-66,47,119,33,-63,-107,-1,103,
  149.   73,-22,-106,-49,69,109,11,-80,-90,22,111,
  150.   49,-46,-106,-22,84,88,-4,-92,-68,52,107,
  151.   23,-63,-95,3,101,66,-28,-98,-36,69,95,
  152.   7,-79,-69,38,100,31,-53,-87,-3,85,63,
  153.   -26,-88,-38,58,88,14,-68,-73,20,87,41,
  154.   -38,-80,-17,68,63,-14,-73,-42,42,79,22,
  155.   -50,-63,11,73,44,-25,-68,-22,53,65,0,
  156.   -58,-44,26,69,28,-41,-61,-3,58,46,-15,
  157.   -65,-38,34,65,17,-42,-53,3,57,38,-23,
  158.   -55,-17,41,49,-1,-52,-41,25,61,22,-38,
  159.   -58,-6,60,53,-7,-60,-39,31,68,25,-39,
  160.   -65,-4,57,47,-11,-60,-36,34,57,11,-44,
  161.   -58,-1,55,41,-12,-55,-31,30,53,17,-33,
  162.   -50,-4,44,39,-3,-42,-30,19,41,12,-26,
  163.   -36,-3,34,31,-3,-34,-28,7,42,20,-12,
  164.   -28,-9,17,22,1,-19,-15,3,15,7,-9,
  165.   -14,-3,9,9,-1,-7,-4,3
  166. };
  167.  
  168. /* To sample sound you have to use a sound sampler. If */
  169. /* you do not have any I can help you and do it for    */
  170. /* you, free of charge. (Registered members only.)     */
  171.  
  172.  
  173.  
  174.  
  175. /* Declare our functions: */
  176. void main();
  177. void clean_up( STRPTR text );
  178.  
  179.  
  180.  
  181. void main()
  182. {
  183.   /* Error messages: */
  184.   BYTE error;
  185.  
  186.   /* The channel we have received: */
  187.   UBYTE channel;
  188.  
  189.   /* Used in the loops: */
  190.   int loop;
  191.  
  192.  
  193.  
  194.   /* Get a reply port: (No name, priority 0) */
  195.   replymp = (struct MsgPort *)
  196.     CreatePort( NULL, 0 );
  197.   if( !replymp )
  198.     clean_up( "Could not create the reply port!" );
  199.  
  200.  
  201.  
  202.   /* Allocate and preinitialize an audio request block: */
  203.   audio_req = (struct IOAudio *)
  204.     CreateExtIO( replymp, sizeof( struct IOAudio ) );
  205.   if( !audio_req )
  206.     clean_up( "Not enough memory for the IOAudio structure!" );
  207.  
  208.  
  209.  
  210.   /* Open the Audio Device: (We will try to */
  211.   /* reserve a sound channel later on.)     */
  212.   error = OpenDevice( AUDIONAME, 0, audio_req, 0 );
  213.   if( error )
  214.   {
  215.     /* Clear the "io_Device" flag since we have not opened the device: */
  216.     audio_req->ioa_Request.io_Device = NULL;
  217.   
  218.     /* Quit: */
  219.     clean_up( "Could not open the Audio Device!" );
  220.   }
  221.  
  222.  
  223.  
  224.   /* Try to reserve a channel: */
  225.   audio_req->ioa_Request.io_Command = ADCMD_ALLOCATE;
  226.  
  227.   /* Set sound priority: (We are going to play a sound effect.) */
  228.   audio_req->ioa_Request.io_Message.mn_Node.ln_Pri = SOUND_EFFECT;
  229.  
  230.   /* Do not wait for any channels to be free, */
  231.   /* return immediately, successfully or not: */
  232.   audio_req->ioa_Request.io_Flags = ADIOF_NOWAIT;
  233.  
  234.   /* Give the request block a pointer to our allocation array: */
  235.   audio_req->ioa_Data = allocation_array;
  236.   
  237.   /* Set the length of the allocation array: */
  238.   audio_req->ioa_Length = sizeof( allocation_array );
  239.          
  240.   /* Do our request: */
  241.   BeginIO( audio_req );
  242.  
  243.   /* Wait for the request to be completed: */
  244.   error = WaitIO( audio_req );
  245.  
  246.   /* Everything OK? */
  247.   if( error )
  248.     clean_up( "No channel available!" );
  249.  
  250.  
  251.  
  252.   /* Check which channel we received: */
  253.   channel = (UBYTE) audio_req->ioa_Request.io_Unit;
  254.  
  255.   /* Check which channel we received: */
  256.   channel = (UBYTE) audio_req->ioa_Request.io_Unit;
  257.  
  258.   if( channel & LEFT0F )
  259.     printf( "First left channel!\n" );
  260.  
  261.   if( channel & RIGHT0F )
  262.     printf( "First right channel!\n" );
  263.  
  264.   if( channel & RIGHT1F )
  265.     printf( "Second right channel!\n" );
  266.  
  267.   if( channel & LEFT1F )
  268.     printf( "Second left channel!\n" );
  269.  
  270.  
  271.  
  272.   /* Allocate some memory where we can store the waveform we   */
  273.   /* want to use. Note that it must be Chip memory, and placed */
  274.   /* on a word boundary!                                       */
  275.   beep_wave = (BYTE *) AllocMem( sizeof( beep_data ), MEMF_CHIP );
  276.   if( !beep_wave )
  277.     clean_up( "Could not allocate enough memory for the beep wave!" );  
  278.  
  279.   /* Copy the beep data to some chip memory: */
  280.   for( loop = 0; loop < sizeof( beep_data ); loop++ )
  281.     beep_wave[ loop ] = beep_data[ loop ];
  282.  
  283.  
  284.   
  285.   /* Give the request block a pointer to the waveform: */
  286.   audio_req->ioa_Data = beep_wave;
  287.  
  288.   /* Set the length of the waveform:    */
  289.   /* (Must be an even number of bytes.) */
  290.   audio_req->ioa_Length = sizeof( beep_data );
  291.  
  292.   /* Play the waveform 1 time: */
  293.   audio_req->ioa_Cycles = 1;
  294.  
  295.   /* Going to play a tune: */
  296.   audio_req->ioa_Request.io_Command = CMD_WRITE;
  297.  
  298.   /* Use the volume and period fields of the request block: */
  299.   /* (If we do not set this flag the previous volume and    */
  300.   /* period values will be used.)                           */
  301.   audio_req->ioa_Request.io_Flags = ADIOF_PERVOL;
  302.  
  303.   /* Medium volume: */
  304.   audio_req->ioa_Volume = 32;
  305.  
  306.   /* Set the period: (The period value can be calculated  */
  307.   /* by dividing the clock constant with the record rate. */
  308.   /* The record rate is also printed by PrintSound,       */
  309.   /* together with the sample data values.)               */
  310.   audio_req->ioa_Period = PAL_CLOCK / 10100;
  311.  
  312.  
  313.  
  314.   /* Tell the user to be prepared: */
  315.   printf( "\"The machine that goes Bing!\"\n" );
  316.  
  317.   /* Start to play the sound: */
  318.   BeginIO( audio_req );
  319.     
  320.   /* Wait for the soiund to be completed: */
  321.   error = WaitIO( audio_req );
  322.  
  323.   /* Was the note successfully played? */
  324.   if( error )
  325.     clean_up( "Error while playing!" );
  326.  
  327.  
  328.  
  329.   /* Clean up and quit: */
  330.   clean_up( "The End!" );
  331. }
  332.  
  333.  
  334.  
  335. /* Close and return everything that has been */
  336. /* opened and allocated before we quit:      */
  337.  
  338. void clean_up( STRPTR text )
  339. {
  340.   /* If we have a request block and it does not contain   */
  341.   /* any errors we know that a channel has been allocated */
  342.   /* and must be deallocated:                             */
  343.   if( audio_req && !(audio_req->ioa_Request.io_Error) )
  344.   {
  345.     /* Free the channel: */
  346.     audio_req->ioa_Request.io_Command = ADCMD_FREE;
  347.  
  348.     /* We are allowed to use the function DoIO() for */
  349.     /* this request since it will not change any     */
  350.     /* values that are vital for us:                 */ 
  351.     DoIO( audio_req );
  352.     
  353.     /* The lock is automatically unlocked when we */
  354.     /* free the audio channel.                    */
  355.   }
  356.  
  357.   /* Empty the reply port: */
  358.   while( GetMsg( replymp ) )
  359.     printf( "Collected a message at the reply port.\n" );
  360.   
  361.   /* If we have a request block and the "io_Device" field  */
  362.   /* is not zero, we know that the device has successfully */
  363.   /* been opened and must now be closed:                   */ 
  364.   if( audio_req && audio_req->ioa_Request.io_Device )
  365.     CloseDevice( audio_req );
  366.  
  367.   /* Remove the replyport: */
  368.   if( replymp )
  369.     DeletePort( replymp);
  370.  
  371.   /* Dealocate the IOAudio structure: */
  372.   if( audio_req )
  373.     DeleteExtIO( audio_req, sizeof( struct IOAudio ) );
  374.  
  375.   /* Dealocate the beep waveform: */
  376.   if( beep_wave )
  377.     FreeMem( beep_wave, sizeof( beep_data ) );
  378.  
  379.   /* Print the last message: */
  380.   printf( "%s\n", text );
  381.  
  382.   /* Quit: */
  383.   exit( 0 );
  384. }
  385.  
  386.  
  387.